/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Classes;

import java.io.*;
import java.net.*;
import java.util.*;

import javax.servlet.*;
import javax.servlet.http.*;
/**
 *
 * @author Ward
 */
public class OpenChooseProject extends HttpServlet {
    
    AE.VarParams            varParams;
    AE.DataConsolidation    dc;
    AE.Data                 analysisProject;
    String                  lastError = null;

   
    /** 
    * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
    * @param request servlet request
    * @param response servlet response
    */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        String requestedMimeType = request.getParameter( "requestedMimeType" ); 
        if( requestedMimeType == null || requestedMimeType.length() == 0 )
            response.setContentType("text/html;charset=UTF-8");  // "text/html;charset=UTF-8" is considered "normal" by the function HelperHtml.IsMimeTypeNormal
        else
            response.setContentType( requestedMimeType );
        
            String FullySpecifiedPathToBaseDirectoryOfFiles=  
                    getServletContext().getInitParameter("OpenChooseProject");
            String sessionId = request.getSession().getId();

            DoMain( FullySpecifiedPathToBaseDirectoryOfFiles, sessionId, request, response, requestedMimeType );

            
    } 
    /**
     * Runs analytical script commands, first from the project then from the list
     * 
     * @param variablesFullFileName identifies config file which contains subdirectories
     * @param sessionId is the unique id of this session in case we need a temporary file
     * @param projectFileName is a file that's in a subdir identified in the config file which contains a list of commands. this file can be "missing" if all you want to do is run script commands from the next param
     * @param linesOfScript is a list of additional script commands
     * 
     * @return If return non-null, something didn't work.
     * 
     */
    
    public void DoMain( String FullySpecifiedPathToBaseDirectoryOfFiles, String sessionId, 
    		HttpServletRequest request,
    		HttpServletResponse response, String requestedMimeType )
    {
        PrintWriter out = null;
        try {
        AE.MyListString linesOfScript = new AE.MyListString();
        
        out = response.getWriter();
        out.println( HelperHtml.GetHead() );
        out.println( "<body>" );
        
        out.println( "Using " + FullySpecifiedPathToBaseDirectoryOfFiles + "\\variables.config <br/>" );

        String errMsg = Init(FullySpecifiedPathToBaseDirectoryOfFiles, sessionId );
        if( errMsg != null )
        {
            out.write( errMsg );
            out.close();
            return;
        }
        
        out.println( "<form method='post' id='form0'   >" );
        out.println( "<h2>Select a project from the following list</h2>" );
        out.println( "<table>" );
        out.println( "<tr>");
        out.println( "<td >");

        ArrayList<String> list = new ArrayList<String>();
        ArrayList<String> files = new ArrayList<String>();
        
        list.add( "" ); // put in one blank entry so that they have a way of unselecting a file
        files.add( "" );

        String projectFileName = request.getParameter( "selectedFile" );
        AE.MyListString filelist = AE.MyDirectory.GetFiles( varParams.GetMyProjectsDir() );
        
        out.write( "<select name='selectedFile' >" );
        for( int fileIndex = 0,  fileCount = filelist.GetCount(); fileIndex < fileCount ; fileIndex++ )
        {
            String shortName = filelist.Get( fileIndex );
            if( shortName.startsWith("_") == false )
            {
                String listControlContents;
                if( (   ( projectFileName == null || projectFileName.length() == 0 ) 
                        && fileIndex == 0 )
                    || 
                        shortName.equalsIgnoreCase( projectFileName  )
                  )
                {
                    listControlContents = String.format( "<option selected='true' value='%s'>%s</option>",
                        filelist.Get( fileIndex ), shortName );
                    projectFileName = shortName;
                }
                
                else
                {
                    listControlContents = String.format( "<option value='%s'>%s</option>",
                        filelist.Get( fileIndex ), shortName );
                }
                out.write( listControlContents + "<br />" );
            }
        }
        out.write( "</select>" );
        out.println( "</td>");
        out.println( "</tr>");
        out.println( "</table>" );
        out.println( "<input type='submit' value='Change Project' name='Change' >" );
        out.println( "</form>" );
        
        String error ;
        if( projectFileName == null || projectFileName.length() == 0 )
        {
           //this is not a fatal error, just don't do anything that requires a project to be selected.
        }
        else if( DoProcessProject( projectFileName, linesOfScript ) != null )
        {
            error = GetLastError();
            out.print( "There was a problem building this project. The error that was reported was: " + error );
        } 
        else
        {
            OutputHtml.RunExecutedProjectToHtml(out, projectFileName, analysisProject);
        }
        
        if( HelperHtml.IsMimeTypeNormal( requestedMimeType ) == false )
        {
            out.close();
            return;
        }
        
        out.println( "<form method='post' id='form1' style='display:none'  >" );
        
        out.println( HelperHtml.GetCheckbox( "I want a chart for each column", "wantColumnCharts", request.getParameter("wantColumnCharts") != null ));
        out.println( HelperHtml.GetCheckbox( "I want a chart for each row", "wantRowCharts", request.getParameter("wantRowCharts") != null ));
        out.println( HelperHtml.GetCheckbox( "I want a chart showing all columns", "wantMultiColumn", request.getParameter("wantMultiColumn") != null ));
        out.println( HelperHtml.GetCheckbox( "I want a chart showing all rows", "wantMultiRow", request.getParameter("wantMultiRow") != null ));
        out.println( HelperHtml.GetSelectBoxOfMimeTypes( "I want a different output format", "requestedMimeType", request.getParameter("requestedMimeType") ));
        out.println( "<input type='submit' value='Submit' name='Submit' >" );
        
        out.println( "</form>" );
        } 
        catch( Exception e )
        {
            if( out != null )
                out.print( e.getLocalizedMessage() );
        }
        finally { 
            if( out != null )
                out.close();
        }
        
    }
    public String DoProcessProject( String projectFileName, AE.MyListString linesOfScript  )
    {
        this.analysisProject = new AE.Data();
        if( this.analysisProject == null )
        {
            lastError = "Failed to load";
            return lastError;
        }

        if( projectFileName != null && projectFileName.length() > 0 )
        {
            String message = this.ExecuteProjectFile( projectFileName, true );
            if( message != null )
            {
                lastError = "Project: " + projectFileName + ". " + message;
                return lastError;
            }
        }

        if( linesOfScript != null && linesOfScript.GetCount() > 0 )
        {
            for( int i = 0, count = linesOfScript.GetCount(); i < count; i++ )
            {
                String thisCommand = linesOfScript.Get( i );
                if( thisCommand != null )
                {
                    thisCommand = thisCommand.trim();
                    if( thisCommand.startsWith(";") == false )
                    {
                        if( localRunScript( thisCommand, true ) == false )
                        {
                            lastError = "problem with script line: " + thisCommand;
                            return lastError;
                        }
                    }
                }
            }
        }
        return null;
    }

    private String ExecuteProjectFile( String projectFileName, Boolean isFirstTime  )
	{
        if (projectFileName == null)
            return projectFileName;

        //////////////////////////////////////////////////////////////////////////////////////////
        //
        // read and process the project file
        //
        String fullProjectFileName = varParams.GetMyProjectsDir() + projectFileName;
        if ( AE.MyFile.Exists(fullProjectFileName) == false )
        {
            lastError = fullProjectFileName;
            return lastError;
        }
        else
        {
            AE.MyListString projectItems = AE.MyFile.ReadAllLines(varParams, fullProjectFileName);

            Integer i;

            if (isFirstTime)
            {
                // Let's scan the stack for relevant operations. We do this by
                // looking backwards in the stack for clearstate operations.
                // Nothing prior to a clearstate needs to be examined.
                for (i = projectItems.GetCount() - 1; i > 0; i--)
                {
                    String thisScriptItem = projectItems.Get(i);
                    if (thisScriptItem.toLowerCase().startsWith("newstartingpoint"))
                    {
                        i++; // skip to the cmd following the clearstate
                        break;
                    }
                }
            }
            else
            {
                // in this situation, do all the transactions, since there might be
                // embedded Save* commands that post clearstate cmds rely upon.
                i = 0;
            }

            if (i >= 0)
            {
                for ( Integer count = projectItems.GetCount(); i < count; i++)
                {
                    String scriptItem = projectItems.Get(i);
                    if ( localRunScript(scriptItem, true ) == false)
                    {
                        String message = "Line " + i.toString() + " failed: " + scriptItem ;
                        varParams.LogError( "Error", message);
                        return message ;
                    }
                }
            }
        }
        return null;    // a return value of null means success 
    }
        
    private boolean localRunScript(String thisScriptItem, boolean initialLoad )
    {
        boolean success = dc.RunScript(thisScriptItem, analysisProject, initialLoad);
        return success;
    }
    public String GetLastError() 
    { 
        if( lastError != null ) 
            return lastError; 
        else 
            return ""; 
    }
    public String Init( String variablesPath, String sessionId )
    {
        this.varParams = new AE.VarParams();
         
        String errMsg = varParams.ReadFile( variablesPath, sessionId );
        if( errMsg != null )
        {
            lastError = errMsg;
            return errMsg ;
        }
        
        this.dc = new AE.DataConsolidation(varParams);

        return null;
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
    * Handles the HTTP <code>GET</code> method.
    * @param request servlet request
    * @param response servlet response
    */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    } 

    /** 
    * Handles the HTTP <code>POST</code> method.
    * @param request servlet request
    * @param response servlet response
    */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
    * Returns a short description of the servlet.
    */
    public String getServletInfo() {
        return "Short description";
    }
    // </editor-fold>
}
